package com.huiminpay.transaction.service.Impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huiminpay.common.cache.Cache;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.execption.BizException;
import com.huiminpay.common.cache.util.EncryptUtil;
import com.huiminpay.common.cache.util.QRCodeUtil;
import com.huiminpay.transaction.api.dto.*;
import com.huiminpay.transaction.api.service.IPayService;
import com.huiminpay.transaction.convert.PayChannelParamConvert;
import com.huiminpay.transaction.convert.PlatformChannelConvert;
import com.huiminpay.transaction.entity.AppPlatformChannel;
import com.huiminpay.transaction.entity.PayChannelParam;
import com.huiminpay.transaction.entity.PlatformChannel;
import com.huiminpay.transaction.mapper.AppPlatformChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelMapper;
import com.huiminpay.transaction.mapper.PayChannelParamMapper;
import com.huiminpay.transaction.mapper.PlatformChannelMapper;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import java.io.IOException;
import java.util.List;
@Service
public class PayServiceImpl implements IPayService {
    @Autowired
    PlatformChannelMapper platformChannelMapper;
    @Autowired
    AppPlatformChannelMapper appPlatformChannelMapper;
    @Autowired
    PayChannelMapper payChannelMapper;
    @Autowired
    PayChannelParamMapper payChannelParamMapper;
    @Autowired
    Cache cache;
    private  String keyPre= "HUIMINPAY_PAYPARAM";
   @Value("${pay.url}")
   private String url;
    @Override
    public String createCScanQRCode(QRCodeDto qrCodeDto) {
        //url地址+票据
        PayOrderDTO payOrderDTO = new PayOrderDTO();
        BeanUtils.copyProperties(qrCodeDto,payOrderDTO);
        payOrderDTO.setChannel("huimin_c2b");
        //先转json在编码

        String ticket= EncryptUtil.encodeUTF8StringBase64(JSON.toJSONString(payOrderDTO));

        String qwAdder= url +ticket;
       //生成二维码
        String qrCode=null;
        try {
            qrCode = new QRCodeUtil().createQRCode(qwAdder, 200, 200);

        } catch (IOException e) {
            throw new BizException(CommonErrorCode.E_200007);

        }
        return qrCode;
    }

    @Override
    public List<PlatformChannelDTO> finaAllPlatformchannel() {
        List<PlatformChannel> platformChannels = platformChannelMapper.selectList(null);
        return PlatformChannelConvert.INSTANCE.listentity2listdto(platformChannels);

    }

    @Override
    public Integer openAppService(String appId, String platformChannelCodes) {
        //唯一校验，服务职能让应用绑定一次
        Integer integer = getAppSS(appId, platformChannelCodes);
        if (integer>0){
            throw new RuntimeException("校验不唯一");

        }
        //保存数据库
        AppPlatformChannel appPlatformChannel = new AppPlatformChannel();
        appPlatformChannel.setAppId(appId);
        appPlatformChannel.setPlatformChannel(platformChannelCodes);

        return appPlatformChannelMapper.insert(appPlatformChannel);
    }

    @Override
    public Integer queryOpenService(String appId, String platformchannel) {
        return getAppSS(appId, platformchannel);
    }



    @Override
    public List<PayChannelDTO> findPlatformChannels(String platformchannelCode) {

        return payChannelMapper.findPlatformChannels(platformchannelCode);
    }



    @Override
    public PayChannelParamDTO savePayChannelParam(PayChannelParamDTO payChannelParamDTO) throws BizException {
        //获取appPlatformChannelId根据appId和platformchannelcode
       AppPlatformChannel appPlatformChannel=getAppplatformchannelId(payChannelParamDTO.getAppId(),payChannelParamDTO.getPlatformChannelCode());
        Long appPlatformChannelId = appPlatformChannel.getId();
        if (appPlatformChannelId==null){
            throw  new BizException(CommonErrorCode.E_100101);
        }

        //保存或者更新

        // 根据appPlatformChannelId和当前的paychannel唯一约束
        QueryWrapper<PayChannelParam > qw = new QueryWrapper<>();
        qw.lambda().eq(PayChannelParam::getAppPlatformChannelId,appPlatformChannelId)
        .eq(PayChannelParam::getPayChannel,payChannelParamDTO.getPayChannel());
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(qw);

        //判断非空是更新
        if (payChannelParam==null){
            //数据插入
          payChannelParam = PayChannelParamConvert.INSTANCE.dto2entity(payChannelParamDTO);
          payChannelParam.setAppPlatformChannelId(appPlatformChannelId);

            payChannelParamMapper.insert(payChannelParam);
        }else {
           //数据的更新
            payChannelParam.setChannelName(payChannelParamDTO.getChannelName());
            payChannelParam.setParam(payChannelParamDTO.getParam());
            payChannelParamMapper.updateById(payChannelParam);
        }
        //更新缓存。保证数据是最新

        updateRedis(payChannelParamDTO, appPlatformChannelId);
        return payChannelParamDTO;
    }
    //更新缓存
    private void updateRedis(PayChannelParamDTO payChannelParamDTO, Long appPlatformChannelId) {
        String key = keyPre+":"+payChannelParamDTO.getAppId()+":"+payChannelParamDTO.getPlatformChannelCode();//产品名+业务名+参数
        cache.del(key);
        List<PayChannelParam> payChannelParams = getPayChannelParams(appPlatformChannelId);
        List<PayChannelParamDTO> list = PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
        cache.set(key, JSON.toJSONString(list));
    }

    @Override
    public List<PayChannelParamDTO> queryPlatformChannelPayParams(String appId, String platformchannel){
        //升级方法
        String key = keyPre+":"+appId+":"+platformchannel;//产品名+业务名+参数
        if (cache.exists(key)){
            //
            String s = cache.get(key);
            List<PayChannelParamDTO> list1 = JSON.parseArray(s, PayChannelParamDTO.class);

            return list1;
        }
        AppPlatformChannel appPlatformChannel=getAppplatformchannelId(appId,platformchannel);
        Long appPlatformChannelId = appPlatformChannel.getId();
        if (appPlatformChannelId==null){
            throw  new BizException(CommonErrorCode.E_100101);
        }
        //查询
        List<PayChannelParam> payChannelParams = getPayChannelParams(appPlatformChannelId);
        List<PayChannelParamDTO> list = PayChannelParamConvert.INSTANCE.listentity2listdto(payChannelParams);
       //保存到redis
        cache.set(key, JSON.toJSONString(list));

        return list;
    }

    @Override
    public PayChannelParamDTO queryPlatformChannelPayParam(String appId, String platformchannel, String payChannel) {
        AppPlatformChannel appPlatformChannel=getAppplatformchannelId(appId,platformchannel);
        Long appPlatformChannelId = appPlatformChannel.getId();
        if (appPlatformChannelId==null){
            throw  new BizException(CommonErrorCode.E_100101);
        }
        //查询
        QueryWrapper<PayChannelParam> qw = new QueryWrapper<>();
        qw.lambda().eq(PayChannelParam::getAppPlatformChannelId,appPlatformChannelId)
                .eq(PayChannelParam::getPayChannel,payChannel);
        PayChannelParam payChannelParam = payChannelParamMapper.selectOne(qw);
        return PayChannelParamConvert.INSTANCE.entity2dto(payChannelParam);
    }

    @Override
    public int queryAppBindPlatformChannel(String appId, String platformChannel) {
        int count = appPlatformChannelMapper.selectCount(
                new QueryWrapper<AppPlatformChannel>().lambda().eq(AppPlatformChannel::getAppId, appId)
                        .eq(AppPlatformChannel::getPlatformChannel, platformChannel));
        //已存在绑定关系返回1
        if (count > 0) {
            return 1;
        } else {
            return 0;
        }
    }


    /**
     * 获取应用绑定服务
     * @param appId
     * @param platformchannel
     * @return
     */


    private  Integer getAppSS(String appId,String platformchannel){
        QueryWrapper<AppPlatformChannel> qw = new QueryWrapper<>();
        qw.lambda().eq(AppPlatformChannel::getAppId,appId)
                .eq(AppPlatformChannel::getPlatformChannel,platformchannel);

        return  appPlatformChannelMapper.selectCount(qw);
    }
    private  AppPlatformChannel getAppplatformchannelId(String appId, String PlatformChannelCode){
        QueryWrapper<AppPlatformChannel> qw = new QueryWrapper<>();
        qw.lambda().eq(AppPlatformChannel::getAppId,appId)
                .eq(AppPlatformChannel::getPlatformChannel,PlatformChannelCode);

       return appPlatformChannelMapper.selectOne(qw);

    }
    private List<PayChannelParam> getPayChannelParams(long appPlatformChannelId){
        QueryWrapper<PayChannelParam> qw = new QueryWrapper<>();
        qw.lambda().eq(PayChannelParam::getAppPlatformChannelId,appPlatformChannelId);
        List<PayChannelParam> payChannelParams = payChannelParamMapper.selectList(qw);
        return payChannelParams;
    }
}
